home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
TECHNICA
/
COMPUTER
/
H254.ZIP
/
IRITSM3S.ZIP
/
IRIT
/
ALLOCATE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-28
|
12KB
|
371 lines
/*****************************************************************************
* "Irit" - the 3d polygonal solid modeller. *
* *
* Written by: Gershon Elber Ver 0.2, Mar. 1990 *
******************************************************************************
* Dynamic allocation module of "Irit" - the 3d polygonal solid modeller. *
*****************************************************************************/
/* #define DEBUG Print more messages in free/allocating. */
#ifdef __MSDOS__
#include <alloc.h>
#include <time.h>
#endif /* __MSDOS__ */
#include <stdio.h>
#include <string.h>
#include "program.h"
#include "allocate.h"
#include "attribut.h"
#include "ctrl-brk.h"
#include "graphgen.h"
#include "windows.h"
#define MAGIC_FREE_NUM 1234567890L /* Used in DEBUG mode to mark free. */
#define ALLOCATE_NUM 100 /* Number of objects to allocate at once. */
#ifdef __MSDOS__
/* Used to say when to update core left on screen: */
static time_t LastTimeAlloc = 0;
#endif /* __MSDOS__ */
/* Used for fast reallocation of most common object types: */
static VertexStruct *VertexFreedList = NULL;
static PolygonStruct *PolygonFreedList = NULL;
static ObjectStruct *ObjectFreedList = NULL;
static void FreePolygonList(PolygonStruct * PPoly);
static void FreeVertexList(VertexStruct * VFirst);
/*****************************************************************************
* My Routine to allocate dynamic memory. All program requests must call this *
* routine (no direct call to malloc). Dies if no memory. *
* In order to reduce the overhead of the allocation, basic objects are *
* allocated in ALLOCATE_NUM number of objects blocks. *
*****************************************************************************/
char *MyMalloc(unsigned int Size, AllocateStructType Type)
{
char *p;
int i;
# ifdef __MSDOS__
if (time(NULL) != LastTimeAlloc) {
if (GlblWasCtrlBrk) FatalError(NULL); /* Jump to main loop. */
WndwStatusWindowUpdate(); /* Print free memory. */
LastTimeAlloc = time(NULL);
}
# endif /* __MSDOS__ */
switch (Type) {
case ALLOC_VERTEX:
# ifdef DEBUG
fprintf(stderr, "MyMalloc: Allocate vertex type");
# endif /* DEBUG */
if (VertexFreedList != NULL) {
p = (char *) VertexFreedList;
VertexFreedList = VertexFreedList -> Pnext;
}
else {
VertexStruct *V;
/* Allocate ALLOCATE_NUM objects, returns first one as new */
/* and chain together the rest of them into the free list. */
p = malloc(Size * ALLOCATE_NUM);
V = (VertexStruct *) p;
if (V != NULL) {
for (i = 1; i < ALLOCATE_NUM-1; i++) V[i].Pnext = &V[i+1];
V[ALLOCATE_NUM-1].Pnext = NULL;
VertexFreedList = &V[1];
}
}
break;
case ALLOC_POLYGON:
# ifdef DEBUG
fprintf(stderr, "MyMalloc: Allocate polygon type");
# endif /* DEBUG */
if (PolygonFreedList != NULL) {
p = (char *) PolygonFreedList;
PolygonFreedList = PolygonFreedList -> Pnext;
}
else {
PolygonStruct *V;
/* Allocate ALLOCATE_NUM objects, returns first one as new */
/* and chain together the rest of them into the free list. */
p = malloc(Size * ALLOCATE_NUM);
V = (PolygonStruct *) p;
if (V != NULL) {
for (i = 1; i < ALLOCATE_NUM-1; i++) V[i].Pnext = &V[i+1];
V[ALLOCATE_NUM-1].Pnext = NULL;
PolygonFreedList = &V[1];
}
}
break;
case ALLOC_OBJECT:
# ifdef DEBUG
fprintf(stderr, "MyMalloc: Allocate object type");
# endif /* DEBUG */
if (ObjectFreedList != NULL) {
p = (char *) ObjectFreedList;
ObjectFreedList = ObjectFreedList -> Pnext;
}
else {
ObjectStruct *V;
/* Allocate ALLOCATE_NUM objects, returns first one as new */
/* and chain together the rest of them into the free list. */
p = malloc(Size * ALLOCATE_NUM);
V = (ObjectStruct *) p;
if (V != NULL) {
for (i = 1; i < ALLOCATE_NUM-1; i++) V[i].Pnext = &V[i+1];
V[ALLOCATE_NUM-1].Pnext = NULL;
ObjectFreedList = &V[1];
}
}
break;
default:
# ifdef DEBUG
fprintf(stderr, "MyMalloc: Allocate undefined Type %d", Type);
# endif /* DEBUG */
p = malloc(Size);
break;
}
# ifdef DEBUG
fprintf(stderr, " (Size = %d, ptr = %p)\n", Size, p);
# endif /* DEBUG */
if (p != NULL) return p;
WndwInputWindowPutStr("Not enough memory - program cannt continue");
GlblFatalError = TRUE;
/* Long jump to main intraction loop - irit.c module */
longjmp(GlblLongJumpBuffer, 2);
return NULL; /* Only makes warnings silent... */
}
/*****************************************************************************
* Routine to free a given structure, which is not needed any more *
* Note usually only object will be given directly to MyFree which *
* recursively free its structure... *
* Also, it is perfectly legal to call with NULL to MyFree... *
*****************************************************************************/
void MyFree(char *p, AllocateStructType Type)
{
int index;
char Line[LINE_LEN];
ObjectStruct *PObj;
# ifdef __MSDOS__
if (time(NULL) != LastTimeAlloc) {
if (GlblWasCtrlBrk) FatalError(NULL); /* Jump to main loop. */
WndwStatusWindowUpdate(); /* Print free memory. */
LastTimeAlloc = time(NULL);
}
# endif /* __MSDOS__ */
if (p == NULL) return;
# ifdef DEBUG
/* The following might fail if a record is freed without any usage! */
if (*((long *) p) == MAGIC_FREE_NUM)
FatalError("MyFree:Free the same record twice, dies");
*((long *) p) = MAGIC_FREE_NUM; /* And set it for next time... */
# endif /* DEBUG */
switch (Type) {
case ALLOC_VERTEX:
# ifdef DEBUG
fprintf(stderr, "MyFree: free vertex type\n");
# endif /* DEBUG */
FreeVertexList((VertexStruct *) p);
break;
case ALLOC_POLYGON:
# ifdef DEBUG
fprintf(stderr, "MyFree: free polygon type\n");
# endif /* DEBUG */
FreePolygonList((PolygonStruct *) p);
break;
case ALLOC_OBJECT:
# ifdef DEBUG
fprintf(stderr, "MyFree: free object type\n");
# endif /* DEBUG */
PObj = (ObjectStruct *) p;
if (PObj -> Count > 1) {
/* Do not free object - just decrease its reference count. */
PObj -> Count--;
break;
}
switch (((ObjectStruct *) p) -> ObjType) {
case UNDEF_OBJ:
break;
case POLY_OBJ: /* Free the polygon list. */
MyFree((char *) (PObj -> U.Pl.P), ALLOC_POLYGON);
ReleaseStrAttrib(PObj);
break;
case NUMERIC_OBJ:
case VECTOR_OBJ:
case CTLPT_OBJ:
case MATRIX_OBJ:
case STRING_OBJ:
break;
case OBJ_LIST_OBJ: /* Need to dereference elements in list. */
index = 0;
while (index < MAX_OBJ_LIST &&
PObj -> U.PObjList[index] != NULL) {
if (PObj -> U.PObjList[index] -> Count-- == 1)
MyFree((char *) (PObj -> U.PObjList[index]),
ALLOC_OBJECT);
index++;
}
break;
case CURVE_OBJ:
CagdCrvFree(PObj -> U.Crv.Crv);
if (PObj -> U.Crv.PLPolys)
CagdPolylineFree(PObj -> U.Crv.PLPolys);
if (PObj -> U.Crv.CtlPoly)
CagdPolylineFree(PObj -> U.Crv.CtlPoly);
ReleaseStrAttrib(PObj);
break;
case SURFACE_OBJ:
CagdSrfFree(PObj -> U.Srf.Srf);
if (PObj -> U.Srf.PLPolys)
CagdPolylineFreeList(PObj -> U.Srf.PLPolys);
if (PObj -> U.Srf.CtlMesh)
CagdPolylineFreeList(PObj -> U.Srf.CtlMesh);
if (PObj -> U.Srf.Polygons)
MyFree((char *) PObj -> U.Srf.Polygons, ALLOC_OBJECT);
ReleaseStrAttrib(PObj);
break;
default: /* Kill the program - something is WRONG! */
sprintf(Line,
"MyFree: Attempt to free undefined Object type %d",
PObj -> ObjType);
FatalError(Line);
break;
}
/* Add it to global freed object list: */
PObj -> Pnext = ObjectFreedList;
ObjectFreedList = PObj;
break;
default:
# ifdef DEBUG
fprintf(stderr, "MyFree: Free undefined Type %d\n", Type);
# endif /* DEBUG */
free(p);
break;
}
}
/*****************************************************************************
* Routine to free a polygon list each consists of circular vertex list. *
*****************************************************************************/
static void FreePolygonList(PolygonStruct *PPoly)
{
PolygonStruct *Ptemp, *PPolyHead = PPoly;
# ifdef DEBUG
fprintf(stderr, "FreePolygonList: free polygon list\n");
# endif /* DEBUG */
while (PPoly) {
FreeVertexList(PPoly -> V);
Ptemp = PPoly;
PPoly = PPoly -> Pnext;
}
/* Now chain this new list to the global freed polygon list: */
Ptemp -> Pnext = PolygonFreedList;
PolygonFreedList = PPolyHead;
}
/*****************************************************************************
* Routine to free a circular vertex list - one polygon contour. *
*****************************************************************************/
static void FreeVertexList(VertexStruct *VFirst)
{
VertexStruct *V = VFirst, *Vtemp;
# ifdef DEBUG
fprintf(stderr, "FreeVertexList: free vertex list\n");
# endif /* DEBUG */
if (VFirst == NULL) return;
do {
Vtemp = V;
V = V -> Pnext;
}
while (V != NULL && V != VFirst); /* Both - circular or NULL terminated. */
/* Now chain this new list to the global freed vertex list: */
Vtemp -> Pnext = VertexFreedList;
VertexFreedList = VFirst;
}
/*****************************************************************************
* Allocate one Vertex Structure: *
*****************************************************************************/
VertexStruct * AllocVertex(ByteType Count, ByteType Tags,
PolygonStruct * PAdj, VertexStruct * Pnext)
{
VertexStruct *p;
p = (VertexStruct *) MyMalloc(sizeof(VertexStruct), ALLOC_VERTEX);
p -> Normal[0] = p -> Normal[1] = p -> Normal[2] = 0.0;
p -> Count = Count;
p -> Tags = Tags;
p -> Pnext = Pnext;
p -> PAdj = PAdj;
return p;
}
/*****************************************************************************
* Allocate one Polygon Structure: *
*****************************************************************************/
PolygonStruct * AllocPolygon(ByteType Count, ByteType Tags,
VertexStruct * V, PolygonStruct * Pnext)
{
PolygonStruct *p;
p = (PolygonStruct *) MyMalloc(sizeof(PolygonStruct), ALLOC_POLYGON);
p -> Plane[0] = p -> Plane[1] = p -> Plane[2] = p -> Plane[3] = 0.0;
p -> Count = Count;
p -> Tags = Tags;
p -> V = V;
p -> Pnext = Pnext;
return p;
}
/*****************************************************************************
* Allocate one Object Structure: *
*****************************************************************************/
ObjectStruct * AllocObject(char *Name, IritObjectType ObjType,
ObjectStruct * Pnext)
{
ObjectStruct *p;
p = (ObjectStruct *) MyMalloc(sizeof(ObjectStruct), ALLOC_OBJECT);
strcpy(p -> Name, Name);
p -> ObjType = ObjType;
p -> Count = 1;
p -> Pnext = Pnext;
p -> U.Pl.P = NULL; /* To be on the safe size... */
p -> U.Crv.PLPolys = NULL;
p -> U.Crv.CtlPoly = NULL;
p -> U.Srf.PLPolys = NULL;
p -> U.Srf.CtlMesh = NULL;
p -> U.Srf.Polygons = NULL;
p -> U.Attr.NumStrAttribs = 0;
return p;
}